// Copyright (c) 2009 Mike Haight, Andy Kipp
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include "stdafx.h"

#pragma once

namespace HandBanana { namespace Core
{
    class NativeInput
    {
    public:
        NativeInput(IDirectInputDevice8W* argDevice) : mDirectInputDevice(argDevice), CurrentKeyStates(mKeyStates1), PreviousKeyStates(mKeyStates2)
        {
            ::ZeroMemory(mKeyStates1, 256);
            ::ZeroMemory(mKeyStates2, 256);
        }

    public:
        void Update(void)
        {
            mDirectInputDevice->GetDeviceState(256, (void**)PreviousKeyStates);

            unsigned char* temp = PreviousKeyStates;
            PreviousKeyStates = CurrentKeyStates;
            CurrentKeyStates = temp;
        }

    public:
        unsigned char* CurrentKeyStates;
        unsigned char* PreviousKeyStates;

    private:
        unsigned char         mKeyStates1[256];
        unsigned char         mKeyStates2[256];
        IDirectInputDevice8W* mDirectInputDevice;

    };


    public ref class Input
    {
    // Constructors
    public:
        /// <summary>
        /// Creates an input object with a window requesting access.
        /// </summary>
        Input(void);


    // Destructor
    public:
        ~Input(void);


    public:
        property Boolean KeyDownState[int]
        {
            Boolean get(int argKey);
        }

        property Boolean KeyUpState[int]
        {
            Boolean get(int argKey);
        }

        property Boolean KeyPressedState[int]
        {
            Boolean get(int argKey);
        }


    // Public Methods
    public:
        void Acquire(Window^ argWindow);
        void Unacquire(void);
        void UpdateKeyStates(void);


    // Private Data Members
    private:
        Boolean                 mAcquired;

        NativeInput*            mNativeInput;
        IDirectInput8W*         mDirectInputObject;
        IDirectInputDevice8W*   mDirectInputDevice;

    };
} }